package com.zxd.service.impl;

import com.zxd.core.Constant;
import com.zxd.dao.FileDao;
import com.zxd.dao.GroupDao;
import com.zxd.entity.File;
import com.zxd.entity.Group;
import com.zxd.entity.Master;
import com.zxd.entity.vo.BaseVo;
import com.zxd.service.FileService;
import com.zxd.utils.DateUtils;
import com.zxd.utils.ImageUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartRequest;

import javax.persistence.criteria.Predicate;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * ImageServiceImpl
 * Created by 涂奕恒 on 2017/10/18 20:02.
 */
@Service
public class FileServiceImpl implements FileService {

    @Autowired
    private FileDao fileDao;

    @Autowired
    private GroupDao groupDao;

    @Override
    public List<File> findAll() {
        return fileDao.findAll();
    }

    @Override
    public Page<File> find(int pageNum, int pageSize) {
        return fileDao.findAll(new PageRequest(pageNum - 1, pageSize, Sort.Direction.DESC, "id"));
    }

    @Override
    public Page<File> find(int pageNum) {
        return find(pageNum, Constant.PAGE_DEF_SIZE);
    }

    @Override
    public File getById(int id) {
        return fileDao.findOne(id);
    }

    @Override
    public void deleteById(int id) {
        fileDao.delete(id);
    }

    @Override
    public File create(File file) {
        return fileDao.save(file);
    }

    @Override
    public File update(File file) {
        return fileDao.save(file);
    }

    @Override
    @Transactional
    public void deleteAll(int[] ids) {
        for (int id : ids) {
            deleteById(id);
        }
    }

    @Override
    public BaseVo uploadFile(HttpServletRequest request, MultipartRequest multipartRequest) {
        BaseVo baseVo = new BaseVo();
        List<Map<String, Object>> list = new ArrayList<>();
        Master master = (Master) request.getSession().getAttribute(Constant.CURRENT_LOGIN_MASTER);

        try {
            MultipartFile file = multipartRequest.getFile("file");

            if (null != file && file.getSize() > 0) {
                // 拼接图片实体信息
                String url = ImageUtils.upload(ImageUtils.getWebPath(request), file);

                File baseFile = new File();
                baseFile.setMaster(master);
                baseFile.setName(file.getOriginalFilename());
                baseFile.setUrl(url);

                // 返回文档ID给前台以作绑定
                Map<String, Object> map = new HashMap<>();
                map.put("file", baseFile);

                list.add(map);

                baseVo.setData(list);
                baseVo.setCount(list.size());
            }
        } catch (Exception e) {
            e.printStackTrace();
            baseVo.setCode(Constant.CHECK_STATUS_SUCCESS);
        }
        return baseVo;
    }

    @Override
    public BaseVo getData(String keyWord, Integer groupId, Integer pageNum, Integer pageSize) {
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> map;
        List<File> fileList = findListByParams(keyWord, groupId, pageNum, pageSize);

        if (pageNum > 1 && fileList.size() == 0) {
            fileList = findListByParams(keyWord, groupId, pageNum - 1, pageSize);
        }

        for (File file : fileList) {
            map = new HashMap<>();
            map.put("id", file.getId());
            map.put("name", file.getName());
            map.put("url", file.getUrl());
            map.put("uploadName", file.getMaster().getName());
            map.put("createTime", DateUtils.longToStringWithFormat(file.getCreateTime(), Constant.DEFAULT_TIME));

            list.add(map);
        }

        BaseVo baseVo = new BaseVo();
        baseVo.setCount(findListByParams(keyWord, groupId, 1, 100000).size());
        baseVo.setData(list);

        return baseVo;
    }

    @Override
    public Integer saveInfo(HttpServletRequest request, MultipartRequest multipartRequest, Integer groupId) {
        try {
            File file = new File();
            MultipartFile uploadFile = multipartRequest.getFile("uploadFile");

            if (null != uploadFile && uploadFile.getSize() > 0) {
                // 拼接图片实体信息
                file.setUrl(ImageUtils.upload(ImageUtils.getWebPath(request), uploadFile));
                file.setName(uploadFile.getOriginalFilename());
            } else {
                return -1;
            }

            Master master = (Master) request.getSession().getAttribute(Constant.CURRENT_LOGIN_MASTER);
            file.setMaster(master);

            Group group = groupDao.findOne(groupId);
            file.setGroup(group);
            file.setDescription(getGroupIds(group));

            fileDao.save(file);
            return 1;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    @Override
    public Integer batchDel(String ids) {
        for (String s : ids.split(",")) {
            deleteById(Integer.parseInt(s));
        }
        return 1;
    }

    private List<File> findListByParams(final String keyWord, final Integer groupId, Integer pageNum, Integer pageSize) {
        return fileDao.findAll((root, query, cb) -> {
            Predicate result = null;
            List<Predicate> predicateList = new ArrayList<>();

            if (StringUtils.isNotBlank(keyWord)) {
                predicateList.add(cb.like(root.get("name").as(String.class), "%" + keyWord + "%"));
            }

            if (null != groupId && groupId != 0) {
                predicateList.add(cb.like(root.get("description").as(String.class), "%id" + groupId + ",%"));
            }

            predicateList.add(cb.isNotNull(root.get("group").get("id").as(Integer.class)));
            predicateList.add(cb.isNotNull(root.get("master").get("id").as(Integer.class)));

            if (predicateList.size() > 0) {
                result = cb.and(predicateList.toArray(new Predicate[]{}));
            }
            if (result != null) {
                query.where(result);
            }
            return query.getGroupRestriction();
        }, new PageRequest(pageNum - 1, pageSize, Sort.Direction.DESC, "id")).getContent();
    }

    private String getGroupIds(Group group) {
        String result = "id" + group.getId() + ",";
        Integer level = group.getLevel();
        Group lv2;
        Group lv1;

        if (level == 3) {
            lv2 = groupDao.findOne(group.getParentId());// 此处是二级节点
            lv1 = groupDao.findOne(lv2.getParentId());// 此处是一级节点

            result += "id" + lv2.getId() + ",id" + lv1.getId() + ",";
        } else if (level == 2) {
            lv1 = groupDao.findOne(group.getParentId());// 此处是一级节点

            result += "id" + lv1.getId() + ",";
        }

        return result;
    }
}